package com.guangli.ocr.ui

import android.Manifest
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.view.Surface
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.lifecycle.Observer
import com.baidu.idcardquality.IDcardQualityProcess
import com.baidu.ocr.sdk.OCR
import com.baidu.ocr.sdk.OnResultListener
import com.baidu.ocr.sdk.exception.OCRError
import com.baidu.ocr.sdk.model.IDCardParams
import com.baidu.ocr.sdk.model.IDCardParams.ID_CARD_SIDE_BACK
import com.baidu.ocr.sdk.model.IDCardParams.ID_CARD_SIDE_FRONT
import com.baidu.ocr.sdk.model.IDCardResult
import com.baidu.ocr.ui.camera.*
import com.baidu.ocr.ui.camera.CameraActivity.CONTENT_TYPE_ID_CARD_BACK
import com.baidu.ocr.ui.camera.CameraActivity.CONTENT_TYPE_ID_CARD_FRONT
import com.blankj.utilcode.util.LogUtils
import com.guangli.base.base.activity.RobotBaseActivity
import com.guangli.base.util.FileUtil
import com.guangli.base.utils.Base64Utils
import com.guangli.ocr.R
import com.guangli.ocr.databinding.ActivityIdentificationCardBinding
import com.guangli.ocr.viewmodel.IdentificationCardViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
//import me.goldze.mvvmhabit.BR
import java.io.File
import java.io.FileOutputStream
import java.io.IOException

class IdentificationCardActivity :
    RobotBaseActivity<ActivityIdentificationCardBinding, IdentificationCardViewModel>() {
    var isNativeEnable = false
    private var outputFile: File? = null
    private var contentType: String = CONTENT_TYPE_ID_CARD_FRONT
    private val permissionCallback = PermissionCallback {
        ActivityCompat.requestPermissions(
            this, arrayOf(Manifest.permission.CAMERA),
            CameraActivity.PERMISSIONS_REQUEST_CAMERA
        )
        false
    }

    override fun initComponents() {
        binding.cameraView.cameraControl.setPermissionCallback(permissionCallback)
        initParams()
        init()
        viewModel.isAndTheLiveEvent.observe(this, Observer {
            contentType = if (it == "0") {
                CONTENT_TYPE_ID_CARD_FRONT
            } else {
                CONTENT_TYPE_ID_CARD_BACK
            }
            setMaskType()
//            binding.cameraView.getCameraControl().resume()
            binding.cameraView.start()
        })
    }

    override fun initContentView(savedInstanceState: Bundle?): Int =
        R.layout.activity_identification_card

    override fun initVariableId(): Int = 1

    private fun init() {
        //  初始化本地质量控制模型,释放代码在onDestory中
        //  调用身份证扫描必须加上 intent.putExtra(CameraActivity.KEY_NATIVE_MANUAL, true); 关闭自动初始化和释放本地模型

        //  初始化本地质量控制模型,释放代码在onDestory中
        //  调用身份证扫描必须加上 intent.putExtra(CameraActivity.KEY_NATIVE_MANUAL, true); 关闭自动初始化和释放本地模型
        CameraNativeHelper.init(
            this, OCR.getInstance(this).license
        ) { errorCode, e ->
            val msg: String
            msg = when (errorCode) {
                CameraView.NATIVE_SOLOAD_FAIL -> "加载so失败，请确保apk中存在ui部分的so"
                CameraView.NATIVE_AUTH_FAIL -> "授权本地质量控制token获取失败"
                CameraView.NATIVE_INIT_FAIL -> "本地质量控制"
                else -> errorCode.toString()
            }
            LogUtils.e("本地质量控制初始化错误，错误原因： $msg")
        }
    }

    private fun recIDCard(idCardSide: String, filePath: String) {
        CoroutineScope(Dispatchers.Main).launch {
            withContext(Dispatchers.Main){
                val param = IDCardParams()
                param.imageFile = File(filePath)
                // 设置身份证正反面
                param.idCardSide = idCardSide
                // 设置方向检测
                param.isDetectDirection = true
                // 设置图像参数压缩质量0-100, 越大图像质量越好但是请求时间越长。 不设置则默认值为20
                param.imageQuality = 100
                OCR.getInstance(this@IdentificationCardActivity).recognizeIDCard(param, object : OnResultListener<IDCardResult?> {
                    override fun onResult(result: IDCardResult?) {
                        LogUtils.e(result)
                        if (result != null) {
                            if(result.wordsResultNumber>0) {
                                when (contentType) {
                                    CONTENT_TYPE_ID_CARD_FRONT -> {

                                        viewModel.name.set(result.name.words)
                                        viewModel.gender.set(result.gender.words)
                                        viewModel.ethnic.set(result.ethnic.words)
                                        viewModel.birth.set(result.birthday.words)
                                        viewModel.address.set(result.address.words)
                                        viewModel.idNumber.set(result.idNumber.words)
                                    }
                                    else -> {
                                        viewModel.signDate.set(result.signDate.words)
                                        viewModel.expiryDate.set(result.expiryDate.words)
                                        viewModel.issuingAuthority.set(result.issueAuthority.words)
                                    }
                                }
                            }
                            LogUtils.e(result.toString())
                        }
//                        binding.cameraView.getCameraControl().resume()
                        binding.cameraView.cameraControl.resume()
                        binding.cameraView.setAbortingScan(false);
                    }

                    override fun onError(error: OCRError) {
                        LogUtils.e(error.message)
                        binding.cameraView.cameraControl.resume()
                        binding.cameraView.setAbortingScan(false);
//                        binding.cameraView.cameraControl.stop()
//                        binding.cameraView.cameraControl.start()
                    }
                })
            }
        }
    }


    override fun onRequestPermissionsResult(
        requestCode: Int, permissions: Array<String?>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            CameraActivity.PERMISSIONS_REQUEST_CAMERA -> {
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    LogUtils.e("binding.cameraView.cameraControl.refreshPermission()")
                    binding.cameraView.cameraControl.refreshPermission()
                } else {
                    Toast.makeText(
                        applicationContext,
                        R.string.camera_permission_required,
                        Toast.LENGTH_LONG
                    )
                        .show()
                }
            }
            CameraActivity.PERMISSIONS_EXTERNAL_STORAGE -> {
            }
            else -> {
            }
        }
    }

    private fun initParams() {
        val outputPath = FileUtil.getSaveFile(getApplication()).getAbsolutePath()
        val token = intent.getStringExtra(CameraActivity.KEY_NATIVE_TOKEN)
        if (token == null) {
            isNativeEnable = false
        }
        if (outputPath != null) {
            outputFile = File(outputPath)
        }
        LogUtils.e(outputFile?.exists())

        setMaskType()
        setOrientation(resources.configuration)
//        cropMaskView.setMaskType(maskType)
    }

    private fun setMaskType(){
        val maskType: Int
        when (contentType) {
            CameraActivity.CONTENT_TYPE_ID_CARD_FRONT -> {
                maskType = MaskView.MASK_TYPE_ID_CARD_FRONT
            }
            CameraActivity.CONTENT_TYPE_ID_CARD_BACK -> {
                maskType = MaskView.MASK_TYPE_ID_CARD_BACK

            }
            CameraActivity.CONTENT_TYPE_BANK_CARD -> {
                maskType = MaskView.MASK_TYPE_BANK_CARD
            }
            CameraActivity.CONTENT_TYPE_PASSPORT -> {
                maskType = MaskView.MASK_TYPE_PASSPORT
            }
            CameraActivity.CONTENT_TYPE_GENERAL -> {
                maskType = MaskView.MASK_TYPE_NONE
            }
            else -> {
                maskType = MaskView.MASK_TYPE_NONE
            }
        }
        binding.cameraView.setEnableScan(true)
        binding.cameraView.setMaskType(maskType, this)
        binding.cameraView.setAutoPictureCallback(autoTakePictureCallback)
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        setOrientation(newConfig)
    }

    private fun setOrientation(newConfig: Configuration) {
        val rotation = windowManager.defaultDisplay.rotation
        val orientation: Int
        var cameraViewOrientation = CameraView.ORIENTATION_PORTRAIT
        when (newConfig.orientation) {
            Configuration.ORIENTATION_PORTRAIT -> {
                cameraViewOrientation = CameraView.ORIENTATION_PORTRAIT
                orientation = OCRCameraLayout.ORIENTATION_PORTRAIT
            }
            Configuration.ORIENTATION_LANDSCAPE -> {
                orientation = OCRCameraLayout.ORIENTATION_HORIZONTAL
                cameraViewOrientation =
                    if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90) {
                        CameraView.ORIENTATION_HORIZONTAL
                    } else {
                        CameraView.ORIENTATION_INVERT
                    }
            }
            else -> {
                orientation = OCRCameraLayout.ORIENTATION_PORTRAIT
                binding.cameraView.setOrientation(CameraView.ORIENTATION_PORTRAIT)
            }
        }
//        takePictureContainer.setOrientation(orientation)
        binding.cameraView.setOrientation(cameraViewOrientation)
//        cropContainer.setOrientation(orientation)
//        confirmResultContainer.setOrientation(orientation)
    }

    private val autoTakePictureCallback: CameraView.OnTakePictureCallback =
        CameraView.OnTakePictureCallback { bitmap ->
            CameraThreadPool.execute {
                try {
                    val fileOutputStream: FileOutputStream =
                        FileOutputStream(outputFile)
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream)
                    bitmap.recycle()
                    fileOutputStream.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
                LogUtils.e(contentType)
                when(contentType){
                    CONTENT_TYPE_ID_CARD_FRONT->{
                        recIDCard(ID_CARD_SIDE_FRONT, outputFile?.absolutePath?:"")
                    }
                    else->{
                        recIDCard(ID_CARD_SIDE_BACK, outputFile?.absolutePath?:"")
                    }

                }

                //                    getRealPathFromURI()
                //                    val intent = Intent()
                //                    intent.putExtra(CameraActivity.KEY_CONTENT_TYPE, contentType)
                //                    setResult(RESULT_OK, intent)
                //                    finish()
            }
        }
    /**
     * 做一些收尾工作
     *
     */
    private fun doClear() {
        CameraThreadPool.cancelAutoFocusTimer()
        if (isNativeEnable) {
            IDcardQualityProcess.getInstance().releaseModel()
        }
    }


    override fun onDestroy() {
        super.onDestroy()
        doClear()
    }
}